<template>
  <div
    class="pie"
    :data-percent="title ? percent + '%' : ''"
    :style="{
      '--w': width,
      '--percent': Math.min(Math.max(percent, 0), 100),
      '--bar-width': Math.min(barWidth, 50),
      '--active-color': activeColor,
      '--center-color': centerColor,
      '--back-color': backColor,
    }"
  ></div>
</template>

<script>
export default {
  name: "pie-chart",
  props: {
    title: {
      type: Boolean,
      default: false,
    },
    activeColor: {
      type: String,
      default: "orange",
    },
    backColor: {
      type: String,
      default: "#eee",
    },
    centerColor: {
      type: String,
      default: "#ffffff00",
    },
    barWidth: {
      type: Number,
      default: 10,
    },
    total: {
      type: Number,
      default: 0,
    },
    width: {
      type: Number,
      default: 200,
    },
  },
  data() {
    return {
      percent: 0,
    }
  },
  watch: {
    percent(newVal) {
      if (newVal >= 100 || newVal === this.total) return
      setTimeout(() => {
        this.percent = newVal + (this.total - newVal > 0 ? 1 : -1)
      }, 16)
    },
    total: {
      handler(newVal) {
        this.percent += newVal > this.percent ? 1 : -1
      },
      immediate: true,
    },
  },
}
</script>

<style scoped lang="less">
.pie {
  position: relative;
  width: calc(var(--w) * 1px);
  aspect-ratio: 1;
  border-radius: 50%;
  overflow: hidden;
  font-size: 40px;
  background: var(--back-color);
}

.pie::before {
  content: attr(data-percent);
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  background: radial-gradient(
      farthest-side,
      var(--center-color) calc((var(--w) / 2 - var(--bar-width)) * 1px),
      transparent calc((var(--w) / 2 - var(--bar-width)) * 1px + 1px)
    ),
    conic-gradient(var(--active-color) calc(var(--percent) * 1%), transparent 0),
    radial-gradient(farthest-side, var(--active-color) 90%, transparent)
      top/calc(var(--bar-width) * 1px) calc(var(--bar-width) * 1px) no-repeat;
}

.pie::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: radial-gradient(farthest-side, var(--active-color) 90%, transparent)
    top/calc(var(--bar-width) * 1px) calc(var(--bar-width) * 1px) no-repeat;
  transform: rotate(calc(var(--percent) / 100 * 360deg));
}

.pie span {
  display: grid;
  place-content: center;
  position: absolute;
  inset: 0;
  z-index: 1;
}
</style>
